/////////////////////////////////////////////////////////
//	File Name	:	"CGame.h"
//
//	Author Name	:	David Brown (DB) and Steven Seufert (SMS)
//
//	Purpose		:	To contain all game related code.
/////////////////////////////////////////////////////////
#include "CGame.h"
#include "CMainMenuState.h"
#include "CHud.h"
#include "CGameProfiler.h"

//this is the main constructor
CGame::CGame(void)
{
	m_pD3D	= NULL;
	m_pTM	= NULL;
	m_pFM	= NULL;
	m_pDI	= NULL;
	m_pCurState = NULL;
	m_pOM	= NULL;
	m_pBF	= NULL;
	
	hwnd;

	m_bTwoPlayerGame = false;

	//temp	= 0;
	//temp	= NULL;

	m_dwTimeStamp = GetTickCount();

	m_nImageID = -1;
	m_nSoundID = -1;

}

CGame::~CGame(void)
{
}

CGame* CGame::GetInstance(void)
{
	//	Lazy instantiation
	static CGame instance;
	return &instance;
}

void CGame::Initialize(HWND hWnd, HINSTANCE hInstance, int nScreenWidth, int nScreenHeight, int nPlayWidth, int nPlayHeight, bool bIsWindowed)
{
	srand(unsigned int(time(0)));

	//	Get pointers to singletons:
	m_pD3D	= CSGD_Direct3D::GetInstance();
	m_pTM	= CSGD_TextureManager::GetInstance();
	m_pFM	= CSGD_FModManager::GetInstance();
	m_pDI	= CSGD_DirectInput::GetInstance();
	m_pBF	= CBitmapFont::GetInstance();
	//m_pOM	= CSGD_ObjectManager::GetInstance();
	//m_pOF	= CSGD_ObjectFactory<string, CBase>::GetInstance();

	hwnd = hWnd;

	

	//	Initialize singletons:
	m_pD3D->InitDirect3D(hWnd, nScreenWidth, nScreenHeight, bIsWindowed, true);
	m_pTM->InitTextureManager( m_pD3D->GetDirect3DDevice(), m_pD3D->GetSprite() );
	m_pFM->InitFModManager(hWnd);
	m_pDI->InitDirectInput(hWnd, hInstance, DI_KEYBOARD | DI_MOUSE, DI_MOUSE);
	if (false == m_pBF->LoadXMLFont("Shrewsburry.fnt"))
	{
		cout << "Failure to load the Shrewsburry font in CGame's Initialize() \n";
	}
	else
	{
		// set the font to Shrewsburry
		m_pBF->SetFont("Shrewsburry.fnt");	
		m_pBF->SetScale(1.0f);
	}

	CHud::GetInstance()->LoadHUDObjects();

	//	Load common assets:
	m_nImageID = -1;
	m_nSoundID = -1;

	//m_pCurState = NULL;
	ChangeState( CMainMenuState::GetInstance() );

	m_nFXVolume = 1.0f;
	m_nMusicVolume = 0.50f;
	m_nMusicPan = 0.0f;
	m_nStartingLives = 5;
	m_nMaxStartingLives = 10;

	

	m_dwPreviousTimeStamp = GetTickCount();

	m_nScreenH	= nScreenHeight;
	m_nScreenW	= nScreenWidth;
	m_nPlayW	= nPlayWidth;
	m_nPlayH	= nPlayHeight;
	//m_bWindowed = bIsWindowed;
	//bIsPaused = false;

	CGameProfiler::GetInstance()->LoadUserSettings("user settings.txt");
	SetWindowMode(m_bWindowed);

	SetGameTime(0);

}

bool CGame::Main(void)
{

	DWORD dwStartTimeStamp = GetTickCount();

	m_fElapsedTime = (float)(dwStartTimeStamp - m_dwPreviousTimeStamp) / 1000.0f;

	m_dwPreviousTimeStamp = dwStartTimeStamp;

	//	3 steps a game does EVERY FRAME
	//	Input
	if(Input() == false)
		return false;

	//	Update
	Update();
	//	Draw
	Render();

	return true;
}

void CGame::Shutdown(void)
{
	ChangeState(NULL);

	//m_pOF->UnregisterClassType("CBase");
	//m_pOF->ShutdownObjectFactory();

	/*if (m_pOM)
	{
		m_pOM->RemoveAllObjects();
		m_pOM->DeleteInstance();
		m_pOM = NULL;
	}*/
	//	Shutdown in opposite order
	if (m_pDI)
	{
		m_pDI->ShutdownDirectInput();
		m_pDI = NULL;
	}
	if (m_pFM)
	{
		m_pFM->ShutdownFModManager();
		m_pFM = NULL;
	}
	if (m_pTM)
	{
		m_pTM->ShutdownTextureManager();
		m_pTM = NULL;
	}
	if (m_pD3D)
	{
		m_pD3D->ShutdownDirect3D();
		m_pD3D = NULL;
	}

}

bool CGame::Input(void)
{
	m_pDI->ReadDevices();	// called ONLY ONCE a frame
	
	if (m_pDI->KeyPressed(DIK_RETURN) && (m_pDI->KeyDown(DIK_LALT) || m_pDI->KeyDown(DIK_RALT)))
	{
		ChangeWindowMode();
	}

	return m_pCurState->Input();
}

void CGame::Update(void)
{
	SetGameTime(GetGameTime() + m_fElapsedTime);
	m_pFM->Update();
	m_pCurState->Update(m_fElapsedTime);

	
}

void CGame::Render(void)
{
	m_pD3D->Clear(0, 0, 0);
	m_pD3D->DeviceBegin();
	m_pD3D->SpriteBegin();

	m_pCurState->Render();

	m_pD3D->SpriteEnd();
	m_pD3D->DeviceEnd();
	m_pD3D->Present();
}

void CGame::ChangeState( IGameState* pNewState )
{
	if( m_pCurState )
	{
		m_pCurState->Exit();
	}

	m_pCurState = pNewState;

	if( m_pCurState )
	{
		m_pCurState->Enter();
	}
}

void CGame::ChangeWindowMode()
{
	m_bWindowed = !m_bWindowed;
		m_pD3D->ChangeDisplayParam(m_nScreenW, m_nScreenH, m_bWindowed);
	m_pDI->ReadDevices();
	
}

// set the game to windowed mode (true) or full screen (false)
void CGame::SetWindowMode(bool windowed)
{
	m_pD3D->ChangeDisplayParam(m_nScreenW, m_nScreenH, windowed);
	m_pDI->ReadDevices();
}